package com.liuzy.controller.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;

@Slf4j
@Component
public class RedisUtil {
    @Value("${spring.redis.host:127.0.0.1}")
    private String host;
    @Value("${spring.redis.port:6379}")
    private Integer port;
    @Value("${spring.redis.password:#{null}}")
    private String password;

    private static JedisPool pool;

    @PostConstruct
    public void init() {
        log.debug("Redis init...");
        pool = new JedisPool(host, port); // 本地环境 或 测试环境
    }

    @PreDestroy
    public void stop() {
        log.debug("Redis stop...");
        pool.destroy();
    }

    public void set(String key, String val) {
        try (RedisConn conn = getRedisConn()) {
            conn.jedis.set(key, val);
        }
    }

    public void set(String key, String val, long seconds) {
        try (RedisConn conn = getRedisConn()) {
            conn.jedis.set(key, val, new SetParams().ex(seconds));
        }
    }

    public boolean setNx(String key, String val, long seconds) {
        try (RedisConn conn = getRedisConn()) {
            return "OK".equals(conn.jedis.set(key, val, new SetParams().nx().ex(seconds)));
        }
    }

    public String get(String key) {
        try (RedisConn conn = getRedisConn()) {
            return conn.jedis.get(key);
        }
    }

    public boolean hset(String key, String field, String val) {
        try (RedisConn conn = getRedisConn()) {
            return conn.jedis.hset(key, field, val) > 0;
        }
    }

    public long hlen(String key) {
        try (RedisConn conn = getRedisConn()) {
            return conn.jedis.hlen(key);
        }
    }

    public String hget(String key, String field) {
        try (RedisConn conn = getRedisConn()) {
            return conn.jedis.hget(key, field);
        }
    }

    public Map<String, String> hgetAll(String key) {
        try (RedisConn conn = getRedisConn()) {
            return conn.jedis.hgetAll(key);
        }
    }

    public RedisConn getRedisConn() {
        return new RedisConn(pool);
    }

    public static final class RedisConn implements AutoCloseable {
        private final Jedis jedis;

        public RedisConn(JedisPool pool) {
            this.jedis = pool.getResource();
        }

        @Override
        public void close() {
            jedis.close();
        }
    }
}
